package com.yhy.common.service;

import cn.hutool.core.lang.Assert;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.yhy.common.api.IWorkflowService;
import com.yhy.common.constants.BusClassType;
import com.yhy.common.constants.BusSelfState;
import com.yhy.common.constants.FunProcess;
import com.yhy.common.constants.OperateType;
import com.yhy.common.dao.BaseMngDao;
import com.yhy.common.dto.BaseMainEntity;
import com.yhy.common.dto.BaseMngDTO;
import com.yhy.common.dto.BaseMngVO;
import com.yhy.common.dto.workflow.WorkflowInfo;
import com.yhy.common.exception.BusinessException;
import com.yhy.common.exception.CustomRuntimeException;
import com.yhy.common.jxls.MyJxlsExportConfig;
import com.yhy.common.jxls.MyJxlsExportSupport;
import com.yhy.common.jxls.MyJxlsImportConfig;
import com.yhy.common.jxls.MyJxlsImportSupport;
import com.yhy.common.utils.BusCenterHelper;
import com.yhy.common.utils.JsonUtils;
import com.yhy.common.utils.SpringContextHolder;
import com.yhy.common.utils.YhyUtils;
import com.yhy.common.vo.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.IOUtils;
import org.jxls.reader.ReaderBuilder;
import org.jxls.reader.XLSReadMessage;
import org.jxls.reader.XLSReadStatus;
import org.jxls.reader.XLSReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static io.netty.util.internal.PlatformDependent.throwException;

@Service
@Transactional(rollbackFor = Exception.class)
public abstract class BaseMngService<T extends BaseMngDTO, E extends BaseMngVO> {

    protected Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Autowired
    private DataSource dataSource;

    @Autowired
    private BusCommonStateService busCommonStateService;
    @Autowired
    private BusExtendService busExtendService;

    public abstract BaseMainService getBaseMainService();

    protected BusExtendService getBusExtendService() {
        return busExtendService;
    }

    protected BusCommonStateService getBusCommonStateService() {
        return busCommonStateService;
    }

    protected SysAttachmentService getSysAttachmentService() {
        return SpringContextHolder.getBean(SysAttachmentService.class);
    }

    protected Boolean needUpdateMainSelfState() {
        return false;
    }

    public void workflowCallbackHandle(String userAccount, BusSelfState busSelfState, WorkflowInfo workflowInfo) {
        E busMainData = null;
        if(BusCenterHelper.isComplexBus(workflowInfo.getBusModule()) || BusCenterHelper.isSimpleHistoryMng(workflowInfo.getBusModule())) {
            busMainData = this.findByBusId(workflowInfo.getBusinessKey());
        } else {
            busMainData = this.findByMainId(workflowInfo.getBusinessKey(), true);
        }
        busMainData.setSelfState(busSelfState.getVal());
        busMainData.setLastUpdateBy(userAccount);
        if(needUpdateMainSelfState()) {
            BaseMainEntity baseMainEntity = JsonUtils.tranObject(busMainData, this.getBusDTOInst().getBusMain().getClass());
            getBaseMainService().updateBusState(baseMainEntity);
        }
        if(BusCenterHelper.isComplexBus(workflowInfo.getBusModule()) || BusCenterHelper.isSimpleHistoryMng(workflowInfo.getBusModule())) {
            getBusCommonStateService().updateBusState(busMainData.getBusId(), workflowInfo.getBusModule(), busSelfState);
        }
        if(busSelfState == BusSelfState.VALID) {
            this.processBusCommonStateOfValid(busMainData);
        }
    }

    /**
     * 获取jdbc模版
     *
     * @return
     */
    protected JdbcTemplate getJdbcTemplate() {
        return new JdbcTemplate(dataSource);
    }

    public T getBusDTOInst() {
        try {
            int index = 0;
            Class clazz = this.getClass();
            Type genType = clazz.getGenericSuperclass();

            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

            return (T) ((Class) params[index]).newInstance();
        } catch (InstantiationException e) {
            throw new CustomRuntimeException("获取getBusDTOInst实例错误", e);
        } catch (IllegalAccessException e) {
            throw new CustomRuntimeException("获取getBusDTOInst实例错误", e);
        }
    }

    public E getBusVOInst() {
        try {
            int index = 1;
            Class clazz = this.getClass();
            Type genType = clazz.getGenericSuperclass();

            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

            return (E) ((Class) params[index]).newInstance();
        } catch (InstantiationException e) {
            throw new CustomRuntimeException("获取BusMainDataVO实例错误", e);
        } catch (IllegalAccessException e) {
            throw new CustomRuntimeException("获取BusMainDataVO实例错误", e);
        }
    }

    public E findByBusId(String busId) {
        E busData = finByBusIdWithHistory(busId, false);
        if(busData == null) {
            busData = finByBusIdWithHistory(busId, true);
        }
        return (E) JsonUtils.tranObject(busData, getBusVOInst().getClass());
    }

    private E finByBusIdWithHistory(String busId, Boolean isHistoryTable) {
        Assert.notBlank(busId);
        T baseDTO = getBusDTOInst();
        E paramBean = getBusVOInst();
        paramBean.setBusId(busId);
        baseDTO.setParamBean(paramBean);
        baseDTO.setHistoryTable(isHistoryTable);
        if (StringUtils.isBlank(baseDTO.getBusModule())) {
            baseDTO.setBusModule(getBusModule());
        }
        if (StringUtils.isBlank(baseDTO.getBusClass())) {
            baseDTO.setBusClass(getBusClass());
        }
        baseDTO.setPageBean(null);

        List<E> rtnList = getBaseMngDao().queryPage(baseDTO);
        if (rtnList == null || rtnList.isEmpty()) {
            return null;
        }
        return rtnList.get(0);
    }

    public E findByMainId(String mainId) {
        E busData = findByMainIdWithHistory(mainId, false, false);
        if(busData == null) {
            busData = findByMainIdWithHistory(mainId, true, false);
        }
        return  (E) JsonUtils.tranObject(busData, getBusVOInst().getClass());
    }

    public E findByMainId(String mainId,Boolean isNew) {
        E busData = findByMainIdWithHistory(mainId, false, isNew);
        return  (E) JsonUtils.tranObject(busData, getBusVOInst().getClass());
    }

    private E findByMainIdWithHistory(String mainId, Boolean isHistoryTable, Boolean isNew) {
        Assert.notBlank(mainId);
        T baseDTO = getBusDTOInst();
        E paramBean = getBusVOInst();
        paramBean.setId(mainId);
        if(isNew) {
            paramBean.setHistoryFlag("N");
        }
        baseDTO.setParamBean(paramBean);
        baseDTO.setHistoryTable(isHistoryTable);

        if (StringUtils.isBlank(baseDTO.getBusModule())) {
            baseDTO.setBusModule(getBusModule());
        }
        if (StringUtils.isBlank(baseDTO.getBusClass())) {
            baseDTO.setBusClass(getBusClass());
        }
        baseDTO.setPageBean(null);

        List<E> rtnList = getBaseMngDao().queryPage(baseDTO);
        if (rtnList == null || rtnList.isEmpty()) {
            return null;
        }
        return rtnList.get(0);
    }


    public List queryPageData(T baseDTO) {
        if (StringUtils.isBlank(baseDTO.getBusModule())) {
            baseDTO.setBusModule(getBusModule());
        }
        if (StringUtils.isBlank(baseDTO.getBusClass())) {
            baseDTO.setBusClass(getBusClass());
        }
        if(baseDTO.getSysUser() == null) {
            baseDTO.setSysUser(YhyUtils.getSysUser());
        }
        PageVO pageBean = baseDTO.getPageBean();
        if (pageBean == null) {
            return getBaseMngDao().queryPage(baseDTO);
        }
        baseDTO.setPageQueryCount("Y");
        Long totalCount = getBaseMngDao().queryPageCount(baseDTO);
        if (totalCount == 0) {
            return Lists.newArrayList();
        }
        baseDTO.getPageBean().setTotalCount(totalCount);
        baseDTO.setPageQueryCount(null);
        PageHelper.startPage(pageBean.getPageNo(), pageBean.getPageSize(), false);
        return getBaseMngDao().queryPage(baseDTO);
    }

    protected abstract BaseMngDao getBaseMngDao();

    /*
    *  操作前参数的初始化
     */
    protected void preSetCommonBaseDto(T baseDto) {
        baseDto.setBusModule(getBusModule());
        baseDto.setBusClass(getBusClass());

        if(StringUtils.isBlank(baseDto.getOperateType())) {
            baseDto.setOperateType(OperateType.CREATE.getVal());
        }
        SysUser sysUser = baseDto.getSysUser();
        if (sysUser == null) {
            sysUser = YhyUtils.getSysUser();
            baseDto.setSysUser(sysUser);
        }
        BaseMngVO busMainData = baseDto.getBusMainData();
        if (sysUser != null && busMainData != null) {
            busMainData.setBusModule(getBusModule());
            busMainData.setBusClass(getBusClass());
            if(StringUtils.isBlank(busMainData.getCreateBy())) {
                busMainData.setCreateBy(sysUser.getUserAccount());
            }
            busMainData.setLastUpdateBy(sysUser.getUserAccount());
            if (StringUtils.isBlank(busMainData.getSysOwnerCpy())) {
                busMainData.setSysOwnerCpy(sysUser.getCpyCode());
            }
            if (StringUtils.isBlank(busMainData.getSysOrgCode())) {
                busMainData.setSysOrgCode(sysUser.getOrgCode());
            }
            BusCommonState busCommonState = baseDto.getBusCommonState();
            if (busCommonState != null) {
                if(StringUtils.isBlank(busCommonState.getBusModule())) {
                    busCommonState.setBusModule(getBusModule());
                }
                if(StringUtils.isBlank(busCommonState.getBusClass())) {
                    busCommonState.setBusClass(getBusClass());
                }
                if (StringUtils.isBlank(busCommonState.getSysOwnerCpy())) {
                    busCommonState.setSysOwnerCpy(sysUser.getCpyCode());
                }
                if (StringUtils.isBlank(busCommonState.getSysOrgCode())) {
                    busCommonState.setSysOrgCode(sysUser.getOrgCode());
                }
                busCommonState.setId(busMainData.getBusId());
                if(StringUtils.isBlank(busCommonState.getCreateBy())) {
                    busCommonState.setCreateBy(sysUser.getUserAccount());
                }
                busCommonState.setLastUpdateBy(sysUser.getUserAccount());
            }
            BusExtendVO busExtend = baseDto.getBusExtend();
            if (busExtend != null) {
                if(StringUtils.isBlank(busExtend.getBusModule())) {
                    busExtend.setBusModule(getBusModule());
                }
                if(StringUtils.isBlank(busExtend.getBusClass())) {
                    busExtend.setBusClass(getBusClass());
                }
                if (StringUtils.isBlank(busExtend.getSysOwnerCpy())) {
                    busExtend.setSysOwnerCpy(sysUser.getCpyCode());
                }
                if (StringUtils.isBlank(busExtend.getSysOrgCode())) {
                    busExtend.setSysOrgCode(sysUser.getOrgCode());
                }
                if(StringUtils.isBlank(busCommonState.getCreateBy())) {
                    busExtend.setCreateBy(sysUser.getUserAccount());
                }
                busExtend.setLastUpdateBy(sysUser.getUserAccount());
            }
        }
    }

    protected void afterProcessCustomDataOfSave(T baseDTO) {

    }

    protected void afterProcessCustomDataOfDelete(E busMainData) {

    }

    public abstract String getBusModule();

    public String getBusClass() {
        return getBusModule() + "-001";
    }


    protected void beforeDeleteOfProcess(E busMainData) {

    }

    protected Integer processMainOfDelete(BaseMainEntity baseMainEntity, E busMainData) {
        return getBaseMainService().deleteById(baseMainEntity);
    }

    protected void processBusCommonStateOfDelete(E busMainData) {
    }

    public void doSingleDelete(T baseDTO, E busMainData) {
        RedisLock redisLock = null;
        try {
            if(!BusCenterHelper.isComplexBus(getBusModule()) && StringUtils.isBlank(busMainData.getSelfState())) {
                busMainData.setSelfState(BusSelfState.DRAFT.getVal());
            }
            if(!BusSelfState.DRAFT.getVal().equals(busMainData.getSelfState())) {
                throw new BusinessException("请选择草稿状态的记录进行删除!");
            }
            //防止同步操作
            String redisLockKey = busMainData.getSysOwnerCpy() + (BusCenterHelper.isComplexBus(getBusModule()) ? busMainData.getSysGenCode() : busMainData.getId());
            if (StringUtils.isNotBlank(redisLockKey)) {
                redisLock = new RedisLock(redisLockKey, 200L); //100ms
                if (!redisLock.lock()) {
                    LOGGER.error("删除的数据已发生变化，请刷新页面重试." + redisLockKey);
                    throw new BusinessException("删除的数据已发生变化，请刷新页面重试.");
                }
            }
            baseDTO.setOperateType(OperateType.DELETE.getVal());
            baseDTO.setFunProcess(StringUtils.defaultIfBlank(busMainData.getFunProcess(),FunProcess.NEW.getVal()));
            beforeDeleteOfProcess(busMainData);

            BaseMainEntity baseMainEntity = JsonUtils.tranObject(busMainData, baseDTO.getBusMain().getClass());
            int updateNum = processMainOfDelete(baseMainEntity, busMainData);

            if(updateNum == 0) {
                LOGGER.error("删除时数据已发生变化，请刷新页面." + JsonUtils.toJson(baseMainEntity));
                throw new BusinessException("删除的数据已发生变化，请刷新页面.");
            }

            processBusCommonStateOfDelete(busMainData);

            //3.业务扩展表
            BusClassType busClassType = BusClassType.getInstByVal(getBusClass());
            if(busClassType != null && busClassType.getExtendMng() && baseDTO.getBusExtend() != null) {
                BusExtendVO busExtend = baseDTO.getBusExtend();
                if(StringUtils.isNotBlank(busExtend.getId())) {
                    getBusExtendService().deleteBusExtendById(busExtend.getId(),getBusModule());
                }
            }

            //4.自定义数据处理
            afterProcessCustomDataOfDelete(busMainData);

            //5.附件处理
            if (BusCenterHelper.isAttachmentMng(getBusModule())) {
                getSysAttachmentService().deleteByMainId(getBusModule(), busMainData.getId());
            }

        } finally {
            if (redisLock != null) {
                redisLock.unlock();
            }
        }
    }

    protected void beforeSaveOfProcess(T baseDTO) {

    }

    public void doSave(T baseDTO) {
        preSetCommonBaseDto(baseDTO);
        BaseMngVO busMainData = baseDTO.getBusMainData();

        if(BusCenterHelper.isOrgsetMng(getBusModule())
                && StringUtils.isBlank(busMainData.getSysOrgCode())
                && StringUtils.isBlank(YhyUtils.getSysUser().getOrgCode())) {
            throw new BusinessException("请在用户中心设置操作默认的组织机构.");
        }

        RedisLock redisLock = null;
        try {
            //防止同步更改
            String redisLockKey = null;
            if (BusCenterHelper.isComplexBus(getBusModule()) && StringUtils.isNotBlank(busMainData.getSysGenCode())) {
                redisLockKey = busMainData.getSysOwnerCpy() + busMainData.getSysGenCode();
            } else if (StringUtils.isNotBlank(busMainData.getId())) {
                redisLockKey = redisLockKey + busMainData.getId();
            }
            if (StringUtils.isNotBlank(redisLockKey)) {
                redisLock = new RedisLock(redisLockKey, 200L); //100ms
                if (!redisLock.lock()) {
                    LOGGER.error("编辑的数据已发生变化，请刷新页面重试." + redisLockKey);
                    throw new BusinessException("编辑的数据已发生变化，请刷新页面重试.");
                }
            }
            beforeSaveOfProcess(baseDTO);

            BaseMainEntity baseMainEntity = JsonUtils.tranObject(baseDTO.getBusMainData(), baseDTO.getBusMain().getClass());
            //1.保存主表
            if (OperateType.CREATE.getVal().equals(baseDTO.getOperateType())) {
                // 变更保存的
                if(BusCenterHelper.isSimpleHistoryMng(getBusModule()) && FunProcess.CHANGE.getVal().equals(busMainData.getFunProcess())) {
                    String oldMainId = busMainData.getOldMainId();
                    getBaseMainService().updateEnableFlagForRecover(oldMainId, "N");
                }
                baseMainEntity.setId(null);
                getBaseMainService().insert(baseMainEntity);
                busMainData.setId(baseMainEntity.getId());
                busMainData.setVersion(1);
            } else {
                int updateNum = getBaseMainService().update(baseMainEntity);
                if(updateNum == 0) {
                    LOGGER.error("编辑的数据已发生变化，请刷新页面." + JsonUtils.toJson(baseMainEntity));
                    throw new BusinessException("编辑的数据已发生变化，请刷新页面.");
                }
                busMainData.setVersion(busMainData.getVersion()+1);
            }

            //2.保存业务表
            processBusCommonStateOfSave(baseDTO, (E) busMainData);

            //3.业务扩展表
            BusClassType busClassType = BusClassType.getInstByVal(getBusClass());
            if(busClassType != null && busClassType.getExtendMng() && baseDTO.getBusExtend() != null) {
                BusExtendVO busExtend = baseDTO.getBusExtend();
                if("N".equals(busExtend.getEnableFlag())) {
                    if(StringUtils.isNotBlank(busExtend.getId())) {
                        getBusExtendService().deleteBusExtendById(busExtend.getId(),getBusModule());
                    }
                } else if(StringUtils.isNotBlank(busExtend.getFormApplyId())){
                    busExtend.setMainId(busMainData.getId());
                    busExtend.setEnableFlag("Y");
                    getBusExtendService().saveOrUpdate(busExtend);
                }
            }

            //4.自定义数据处理
            afterProcessCustomDataOfSave(baseDTO);

            //5.附件处理
            List<SysAttachment> attachmentList = baseDTO.getAttachmentList();
            if (CollectionUtils.isNotEmpty(attachmentList)) {
                if (!baseDTO.getOperateType().equals(OperateType.CREATE.getVal())) {
                    getSysAttachmentService().deleteByMainId(getBusModule(), baseMainEntity.getId());
                }
                for (SysAttachment attachment : attachmentList) {
                    //避免复制时ID重复
                    if(StringUtils.isNotBlank(attachment.getMainId()) && !attachment.getMainId().equals(baseMainEntity.getId())) {
                        attachment.setId(null);
                    }
                    attachment.setBusModule(getBusModule());
                    attachment.setMainId(baseMainEntity.getId());
                    //attachment.setId(null);
                    getSysAttachmentService().insert(attachment);
                }
            }
        } finally {
            if (redisLock != null) {
                redisLock.unlock();
            }
        }
        if(baseDTO.getFormSubmit() || baseDTO.getListSubmit()) {
            handleSubmitOfAfterSave(baseDTO);
        }
    }

    protected void processBusCommonStateOfSave(T baseDTO, E busMainData) {

    }

    public void handleSubmitOfAfterSave(T baseDTO) {
        //保存时的提交处理
        E busMainData = (E) baseDTO.getBusMainData();
        this.doSingleSubmit(busMainData);
    }

    protected void beforeSubmitOfProcess(E busMainData) {

    }

    protected void beforeSubmitOfWorkflowInfo(WorkflowInfo workflowInfo, E busMainData) {
        workflowInfo.setTaskTitle("流程业务审批");
        workflowInfo.setTaskDesc("流程业务审批描述");
    }

    protected BusSelfState startWorkflowOfBusiness(String userAccount, E busMainData) {
        //return BusSelfState.VALID;
        IWorkflowService workflowService = SpringContextHolder.getBean(IWorkflowService.SERVICE_BEAN);
        Map<String,Object> paramMap = Maps.newHashMap();
        paramMap.put("busMainData",busMainData);
        WorkflowInfo workflowInfo = new WorkflowInfo();
        workflowInfo.setPassByDirect(busMainData.getPassDirect());
        workflowInfo.setBusinessKey(busMainData.getId());
        workflowInfo.setBusModule(getBusModule());
        workflowInfo.setBusClass(getBusClass());
        workflowInfo.setCreateBy(userAccount);
        //workflowInfo.setSysOrgCode(busMainData.getSysOrgCode());
        workflowInfo.setSysOwnerCpy(busMainData.getSysOwnerCpy());
        beforeSubmitOfWorkflowInfo(workflowInfo, busMainData);
        return workflowService.submitWorkflow(userAccount, workflowInfo, paramMap);
    }

    protected void afterProcessCustomDataOfSubmit(E busMainData) {

    }

    public void processBusCommonStateOfValid(E busMainData) {

    }

    public void doSingleSubmit(E busMainData) {
        RedisLock redisLock = null;
        try {
            Set<String> submitStats = Sets.newHashSet(BusSelfState.DRAFT.getVal(),BusSelfState.APPROVE_NOT_PASS.getVal());
            if(!submitStats.contains(busMainData.getSelfState())) {
                throw new BusinessException("请选择草稿/审批不通过状态的记录进行提交!");
            }
            if(!"N".equals(StringUtils.defaultIfBlank(busMainData.getHistoryFlag(),"N"))) {
                throw new BusinessException("请选择最新版本进行提交!");
            }
            //防止同步操作
            String redisLockKey = busMainData.getSysOwnerCpy() + StringUtils.defaultIfBlank(busMainData.getSysGenCode(),busMainData.getId());
            if (StringUtils.isNotBlank(redisLockKey)) {
                redisLock = new RedisLock(redisLockKey, 200L); //100ms
                if (!redisLock.lock()) {
                    LOGGER.error("数据已发生变化，请刷新页面重试." + redisLockKey);
                    throw new BusinessException("数据已发生变化，请刷新页面重试.");
                }
            }
            beforeSubmitOfProcess(busMainData);

            SysUser sysUser = YhyUtils.getSysUser();
            //启动工作流
            BusSelfState busSelfState = startWorkflowOfBusiness(sysUser.getUserAccount(), busMainData);
            busMainData.setSelfState(busSelfState.getVal());
            BaseMainEntity baseMainEntity = JsonUtils.tranObject(busMainData, getBusDTOInst().getBusMain().getClass());

            //复杂业务, 更新业务表状态
            if(BusCenterHelper.isComplexBus(getBusModule())) {
                int updateNum = getBaseMainService().updateVersion(baseMainEntity);
                if(updateNum == 0) {
                    LOGGER.error("复杂业务提交时数据已发生变化，请刷新页面." + JsonUtils.toJson(baseMainEntity));
                    throw new BusinessException("提交时数据已发生变化，请刷新页面.");
                }
                getBusCommonStateService().updateBusState(busMainData.getBusId(),getBusModule(),busSelfState);
            } else {
                // 简单业务
                int updateNum = getBaseMainService().updateBusState(baseMainEntity);
                if(updateNum == 0) {
                    LOGGER.error("简单业务提交时数据已发生变化，请刷新页面." + JsonUtils.toJson(baseMainEntity));
                    throw new BusinessException("提交时数据已发生变化，请刷新页面.");
                }
                busMainData.setVersion(busMainData.getVersion()+1);
                if(BusCenterHelper.isSimpleHistoryMng(getBusModule())) {
                    getBusCommonStateService().updateBusState(busMainData.getBusId(),getBusModule(),busSelfState);
                }
            }
            //提交后的处理
            afterProcessCustomDataOfSubmit(busMainData);

            if(BusSelfState.VALID == busSelfState) {
                processBusCommonStateOfValid(busMainData);
            }

        } finally {
            if (redisLock != null) {
                redisLock.unlock();
            }
        }
    }

    protected void afterOfProcessLoadData(T baseDTO) {

    }

    public void loadData(T baseDTO) {
        preSetCommonBaseDto(baseDTO);
        //1.分页查找
        E paramBean = (E) baseDTO.getParamBean();
        if(paramBean == null) {
            paramBean = getBusVOInst();
            baseDTO.setParamBean(paramBean);
        }
        paramBean.setHistoryFlag("N");
        List<E> rtnList = queryPageData(baseDTO);
        baseDTO.setRtnList(rtnList);

        afterOfProcessLoadData(baseDTO);
    }

    public void toViewData(T baseDTO) {
        preSetCommonBaseDto(baseDTO);
        beforeProcessOfToView(baseDTO);

        E busMainData = findByMainId(baseDTO.getParamBean().getId());
        baseDTO.setBusMainData(busMainData);
        baseDTO.setFunProcess(StringUtils.defaultIfBlank(busMainData.getFunProcess(),FunProcess.NEW.getVal()));
        baseDTO.setOperateType(OperateType.EDIT.getVal());

        if (BusCenterHelper.isComplexBus(getBusModule())) {
            BusCommonState busCommonState = JsonUtils.tranObject(baseDTO.getBusMainData(), BusCommonState.class);
            busCommonState.setId(busMainData.getBusId());
            baseDTO.setBusCommonState(busCommonState);
        }

        //业务扩展表
        BusClassType busClassType = BusClassType.getInstByVal(getBusClass());
        if(busClassType != null && busClassType.getExtendMng()) {
            BusExtendVO busExtend = getBusExtendService().findByBusModuleAndMainId(getBusModule(), busMainData.getId());
            baseDTO.setBusExtend(busExtend == null ? new BusExtendVO() : busExtend);
        }

        //附件
        if (BusCenterHelper.isAttachmentMng(getBusModule())) {
            List<SysAttachment> sysAttachments = getSysAttachmentService().findByMainId(getBusModule(),busMainData.getId());
            baseDTO.setAttachmentList(sysAttachments);
        }

        afterProcessOfToView(baseDTO);
    }

    protected void beforeProcessOfToView(T baseDTO) {

    }
    protected void afterProcessOfToView(T baseDTO) {

    }

    protected void processOfToAdd(T baseDTO) {
    }

    public void toAddData(T baseDTO) {
        preSetCommonBaseDto(baseDTO);
        E busMainData = baseDTO.getBusMainData() == null ? this.getBusVOInst() : (E) baseDTO.getBusMainData();
        baseDTO.setFunProcess(FunProcess.NEW.getVal());
        baseDTO.setOperateType(OperateType.CREATE.getVal());

        busMainData.setFunProcess(FunProcess.NEW.getVal());
        busMainData.setSelfState(BusSelfState.DRAFT.getVal());
        busMainData.setParentId(null);
        busMainData.setId(null);
        busMainData.setBusId(null);
        busMainData.setSysGenCode(null);
        baseDTO.setBusMainData(busMainData);

        if (BusCenterHelper.isComplexBus(getBusModule())) {
            BusCommonState busCommonState = JsonUtils.tranObject(baseDTO.getBusMainData(), BusCommonState.class);
            busCommonState.setId(null);
            busCommonState.setParentId(null);
            baseDTO.setBusCommonState(busCommonState);
        }

        //业务扩展表
        BusClassType busClassType = BusClassType.getInstByVal(getBusClass());
        if(busClassType != null && busClassType.getExtendMng()) {
            baseDTO.setBusExtend(new BusExtendVO());
        }
        //附件
        if (BusCenterHelper.isAttachmentMng(getBusModule())) {
            List<SysAttachment> sysAttachments = Lists.newArrayList();
            baseDTO.setAttachmentList(sysAttachments);
        }

        processOfToAdd(baseDTO);
    }

    protected void processOfToCopy(T baseDTO) {
    }

    public void toCopyData(T baseDTO) {
        preSetCommonBaseDto(baseDTO);
        E busMainData = findByMainId(baseDTO.getParamBean().getId(), true);
        baseDTO.setFunProcess(FunProcess.NEW.getVal());
        baseDTO.setOperateType(OperateType.CREATE.getVal());
        busMainData.setFunProcess(FunProcess.NEW.getVal());
        busMainData.setSelfState(BusSelfState.DRAFT.getVal());
        busMainData.setOldMainId(baseDTO.getParamBean().getId());
        busMainData.setId(null);
        busMainData.setSysGenCode(null);
        busMainData.setLastUpdateDate(null);
        busMainData.setLastUpdateBy(null);
        baseDTO.setBusMainData(busMainData);
        if (BusCenterHelper.isComplexBus(getBusModule())) {
            busMainData.setParentId(null);
            BusCommonState busCommonState = JsonUtils.tranObject(baseDTO.getBusMainData(), BusCommonState.class);
            busCommonState.setId(null);
            busCommonState.setParentId(null);
            baseDTO.setBusCommonState(busCommonState);
        }

        //业务扩展表
        BusClassType busClassType = BusClassType.getInstByVal(getBusClass());
        if(busClassType != null && busClassType.getExtendMng()) {
            BusExtendVO busExtend = getBusExtendService().findByBusModuleAndMainId(getBusModule(),busMainData.getOldMainId());
            busExtend = busExtend == null ? new BusExtendVO() : busExtend;
            busExtend.setId(null);
            busExtend.setMainId(null);
            String formApplyId = busExtend.getFormApplyId();
            busExtend.setSourceFormApplyId(formApplyId);
            //busExtend.setFormApplyId(null);
            baseDTO.setBusExtend(busExtend);
        }

        //附件
        if (BusCenterHelper.isAttachmentMng(getBusModule())) {
            List<SysAttachment> sysAttachments = getSysAttachmentService().findByMainId(getBusModule(), busMainData.getOldMainId());
            baseDTO.setAttachmentList(sysAttachments);
        }

        processOfToCopy(baseDTO);
    }

    /*
     *  下载导入文件模板
     *  @return 文件名
     */
    public String downloadImportTemplate(T baseDTO, OutputStream outputStream) {
        InputStream importTemplate = null;
        try {
            MyJxlsImportConfig jxlsImportConfig = BusCenterHelper.getBusSourceInfoByBusModuleCode(getBusModule()).getJxlsImportConfig();
            importTemplate = YhyUtils.getInputStream(jxlsImportConfig.getTemplatePath());
            IOUtils.copy(importTemplate, outputStream);
            return jxlsImportConfig.getTemplateName();
        } catch (Exception e) {
            throw new CustomRuntimeException("下载失败。", e);
        } finally {
            IOUtils.closeQuietly(importTemplate);
        }
    }

    /*
     *  处理打印
     *  @return 文件名
     */
    public void processPrint(T baseDTO, OutputStream outputStream) {
        SysPrintMainVO printMainVO = baseDTO.getPrintMain();
        MyJxlsExportConfig myJxlsExportConfig = new MyJxlsExportConfig();
        myJxlsExportConfig.setExportSupportBean(printMainVO.getPrintBean());
        myJxlsExportConfig.setTemplatePath(printMainVO.getAttachmentPath());

        MyJxlsExportSupport jxlsExportSupport = SpringContextHolder.getBean(printMainVO.getPrintBean());
        jxlsExportSupport.setJxlsExportConfig(myJxlsExportConfig);
        baseDTO.setBusModule(getBusModule());
        baseDTO.setBusClass(getBusClass());
        //数据初始化
        Map<String,Object> datas = jxlsExportSupport.processDatas(baseDTO);
        //导出
        jxlsExportSupport.exportData(datas, outputStream);
    }

    /*
    *  处理导出
    *  @return 文件名
     */
    public String processExport(T baseDTO, OutputStream outputStream ) {
        SysPrintMainVO printMainVO = baseDTO.getPrintMain();
        MyJxlsExportConfig myJxlsExportConfig = null;

        if(printMainVO != null) {
            myJxlsExportConfig = new MyJxlsExportConfig();
            myJxlsExportConfig.setExportSupportBean(printMainVO.getPrintBean());
            myJxlsExportConfig.setTemplatePath(printMainVO.getAttachmentPath());
        } else {
            myJxlsExportConfig = BusCenterHelper.getBusSourceInfoByBusModuleCode(getBusModule()).getJxlsExportConfig();
        }
        MyJxlsExportSupport jxlsExportSupport = SpringContextHolder.getBean(myJxlsExportConfig.getExportSupportBean());
        jxlsExportSupport.setJxlsExportConfig(myJxlsExportConfig);
        baseDTO.setBusModule(getBusModule());
        baseDTO.setBusClass(getBusClass());
        //数据初始化
        Map<String,Object> datas = jxlsExportSupport.processDatas(baseDTO);
        //导出
        jxlsExportSupport.exportData(datas, outputStream);

        String templatePath = myJxlsExportConfig.getTemplatePath();
        String fileName = Calendar.getInstance().getTimeInMillis() + templatePath.substring(templatePath.lastIndexOf("."));

        return fileName;
    }

    /*
     *  处理导入
     *  @return 文件名
     */
    public void processImport(T baseDTO,InputStream xlsDataStream) {
        MyJxlsImportConfig jxlsImportConfig = BusCenterHelper.getBusSourceInfoByBusModuleCode(getBusModule()).getJxlsImportConfig();
        MyJxlsImportSupport jxlsImportSupport = SpringContextHolder.getBean(jxlsImportConfig.getImportSupportBean());
        baseDTO.setBusModule(getBusModule());
        baseDTO.setBusClass(getBusClass());
        jxlsImportSupport.setBaseDTO(baseDTO);
        jxlsImportSupport.setJxlsImportConfig(jxlsImportConfig);

        Map<String, Object> datas = jxlsImportSupport.initDatas(xlsDataStream);
        InputStream configStream = null;
        try {
            //自定义导入格式
            if (jxlsImportSupport.isCustomReader()) {
                jxlsImportSupport.handleData(datas);
            } else {
                configStream = YhyUtils.getInputStream(jxlsImportConfig.getConfigPath());
                XLSReader reader = ReaderBuilder.buildFromXML(configStream);
                // 数据解析
                XLSReadStatus readStatus = reader.read(xlsDataStream, datas);

                if (readStatus.isStatusOK()) {
                    // 数据处理
                    jxlsImportSupport.handleData(datas);
                } else {
                    for (XLSReadMessage errorMessage : (List<XLSReadMessage>) readStatus.getReadMessages()) {
                        throwException(errorMessage.getException());
                    }
                }
            }
        } catch (Exception e) {
            throwException(e);
        } finally {
            IOUtils.closeQuietly(configStream);
        }
    }

}
